Debugging Threads
Threads
play a major role in parallel applications. For debugging purposes,
you’ll find thread information in the Threads window. As with most
debugging windows, select Debug | Windows to open the Threads window.
You’ll often want to use the Call Stack and the Threads windows
together; if you open one of these windows, you should probably open the
other. Selections in the Threads window, such as the current thread,
can affect the results shown in the Call Stack window.
The following image shows the Threads window.
The application itself is trivial. It was created
solely to demonstrate various aspects of the debug windows.
As shown in the Threads window, this sample application hosts a variety
of threads.
There are several columns in the Threads window; the first two columns are untitled.
-
First column (no heading)
. This is for flags. Flagging a thread allows you to group, highlight, or filter threads.
-
Second column (no heading)
. This is the active threads column. A yellow arrow
indicates the current thread. If a white arrow appears in this column,
it indicates a thread that has been interrupted by the debugger.
-
ID
. The ID is the operation system identifier for the thread.
-
Managed ID
. This is the common language runtime (CLR) identifier for the thread.
-
Category
. The Category is the type of thread, such as the Main or Worker thread.
-
Name
. This contains the name assigned to the thread, if any. You should always name threads, because it makes debugging easier.
-
Location
. This is the entry point method for the thread. When
you point to a row in this column, the call stack for that thread is
displayed (see the following figure).
-
Priority
. The last column is the thread priority.
The columns are easy to change and organize. Click a column heading
to sort on that column. You can also drag column headers to reorder the
location of columns and add columns by using the Columns arrow at the
right end of the Columns label.
A
right-click context menu is available for the threads in the Threads
window. Two of the commands on the context menu are Switch To Thread and
Freeze. Switching to a thread makes the chosen thread the current
thread. You can also double-click a thread in the Threads window to
perform the switch. In either case, the yellow arrow will move to that
thread row. The Freeze command suspends a thread. You can use this
command to isolate threads that are running the same source code.
What are all of these threads doing? You can discover that by
pointing to the Location column for a particular thread to present the
Call Stack window. You’ll find a persistent view of this information in
the Call Stack window. When you change the current thread in the Threads
window, the content of the Call Stack window updates to reflect the new
selection. The following image shows both the Threads window and Call
Stack window.
By
default, external code might not be shown in the Call Stack window
because it tends to clutter the window. To view external code,
right-click to open the context menu in the Call Stack window. Select
Show External Code to immediately view the external code, as shown in
the next image.
Examine the bottom half of the preceding Call Stack window. You’ll
see clear evidence of a task being created, queued, and finally invoked
on a thread in the .NET Framework 4 thread pool. This is evidence of a
parallel application. In the Call Stack window, you can expand the Name
column to view parameters and other information pertaining to the
method. For example, this is the detailed information for the ExecuteWithThreadLocal method. You can see that the Task ID and an entry point method are the parameters.
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref
System.Threading.Tasks.Task currentTaskSlot = Id = 4,
Status = Running, Method = "Void MA(System.Object)") + 0x160 bytes
You might think that there must be a more direct way to obtain this
information. Of course there is! Visual Studio 2010 offers two new
debugging windows, Parallel Tasks and Parallel Stacks, for viewing tasks
more directly.